package info.sixcorners.thesixcornersapp.client.login;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.i18n.client.Messages;
import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.user.client.ui.*;

/**
 * This is the panel for logging in.
 * Includes a login button and box. When logged in, an Account Management link is displayed.
 */
public class LoginPanel extends Composite {
	@DefaultLocale()
	public static interface LpMessages extends Messages {
		@DefaultMessage("Login")
		String lpLogin();
		@DefaultMessage("Logout")
		String lpLogout();
		@DefaultMessage("Account Management")
		String lpAccountManagement();
		@DefaultMessage("Ok")
		String lpOk();
		@DefaultMessage("Apply")
		String lpApply();
		@DefaultMessage("Cancel")
		String lpCancel();
	}
	private static final LpMessages messages = GWT.create(LpMessages.class);
	private static final LoginServiceAsync loginService = GWT.create(LoginService.class);
	
	private final LoginHandler loginHandler = new LoginHandler();
	private final AccountManagementHandler accMgmtHandler = new AccountManagementHandler();
	
	private final TextBox usernameBox = new TextBox();
	private final Hyperlink accountManagementLink = new Hyperlink(messages.lpAccountManagement(), "accManagement");
	private final Button submitButton = new Button();
	public String sessionID = Cookies.getCookie("sessionID");
	
	/**
	 * @param p: Should either be a HorizontalPanel or a VerticalPanel.
	 */
	public LoginPanel(CellPanel p) {
		usernameBox.setText("No login atm.");
		initWidget(p);
		p.setSpacing(4);
		p.add(usernameBox);
		p.add(accountManagementLink);
		p.add(submitButton);
		
		// Add a handlers
		submitButton.addClickHandler(loginHandler);
		usernameBox.addKeyUpHandler(loginHandler);
		accountManagementLink.addClickHandler(accMgmtHandler);
	}
	
	/**
	 * Handles events for the login TextBox and Button.
	 * Contacts the server.
	 */
	private class LoginHandler implements ClickHandler, KeyUpHandler {
		@Override
		public void onClick(ClickEvent event) {
			login();
		}
		@Override
		public void onKeyUp(KeyUpEvent event) {
			if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
				login();
			}
		}
		
		/**
		 * Sends the current sessionID to the server and replaces it with whatever is returned.
		 * For more information please see {@link info.sixcorners.thesixcornersapp.client.login.LoginService.login(String, boolean)}
		 */
		public void login() {
			submitButton.setEnabled(false);
			// if logged in, pass null for logout
			loginService.login(sessionID == null ? usernameBox.getText() : null, sessionID == null,
					new AsyncCallback<String>() {
						@Override
						public void onFailure(Throwable caught) {
							// Convenient way to find out which exception was thrown.
							try {
//								throw caught;
							} catch (IncompatibleRemoteServiceException e) {
								// this client is not compatible with the server; cleanup and refresh the browser
								// TODO: save all data to cookies, refresh and replace data, clean up cookies
							} catch (InvocationException e) {
								// the call didn't complete cleanly
							}
							submitButton.setEnabled(true);
						}
						@Override
						public void onSuccess(String result) {
							sessionID = result;
							Cookies.setCookie("sessionID", result, new Date(), "", "/", true);
							usernameBox.setVisible(result == null);
							accountManagementLink.setVisible(result != null);
							submitButton.setText(result == null ? messages.lpLogin() : messages.lpLogout());
							submitButton.setEnabled(true);
						}
					});
		}
	}

	/**
	 * Handles events for the 'Account Management' link and it's DialogBox.
	 */
	class AccountManagementHandler implements ClickHandler {
		final DialogBox accManagementBox = new DialogBox();
		final VerticalPanel dialogVPanel = new VerticalPanel();
		{
			accManagementBox.setAnimationEnabled(true);
			accManagementBox.setText(messages.lpAccountManagement());
			accManagementBox.setWidget(dialogVPanel);
			dialogVPanel.addStyleName("dialogVPanel");
//			dialogVPanel.add(accDataPanel);
		}
		
		final HorizontalPanel okApplyCancel = new HorizontalPanel();
		final Button okBtn = new Button(messages.lpOk());
		final Button applyBtn = new Button(messages.lpApply());
		final Button cancelBtn = new Button(messages.lpCancel());
		{
			okApplyCancel.setSpacing(4);
			okApplyCancel.add(okBtn);
			okApplyCancel.add(applyBtn);
			okApplyCancel.add(cancelBtn);
			dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
			dialogVPanel.add(okApplyCancel);
			okBtn.addClickHandler(this);
			applyBtn.addClickHandler(this);
			cancelBtn.addClickHandler(this);
		}
		
		/**
		 * Fires when the user clicks on the 'Account Management' link or any of the DialogBox's bottom buttons.
		 */
		@Override
		public void onClick(ClickEvent event) {
			Element e = event.getRelativeElement();
			if (e == accountManagementLink.getElement()) {
				accManagementBox.center();
				cancelBtn.setFocus(true);
			} else if (e == okBtn.getElement()) {
//				accDataPanel.saveAccountData();
				accManagementBox.hide();
			} else if (e == applyBtn.getElement()) {
//				accDataPanel.saveAccountData();
			} else if (e == cancelBtn.getElement()) {
				accManagementBox.hide();
			}
		}
	};
}
